#ifndef __M_EXTEND_H__
#define __M_EXTEND_H__

// 验证是否支持扩展落地方式
// 扩展按时间滚动输出文件

#include "../log/sink.hpp"

enum class TimeGap
{
    GAP_SECONDE,
    GAP_MINUTE,
    GAP_HOUR,
    GAP_DAY
};

class TimeRollSink : public log::Sink
{
public:
    TimeRollSink(const std::string &basename, TimeGap& gap)
        : _basename(basename)
    {
        switch (gap)
        {
        case TimeGap::GAP_SECONDE:
            _cur_size = 1;
            break;
        case TimeGap::GAP_MINUTE:
            _cur_size = 60;
            break;
        case TimeGap::GAP_HOUR:
            _cur_size = 3600;
            break;
        case TimeGap::GAP_DAY:
            _cur_size = 3600 * 24;
            break;
        }
        _cur_gap = _cur_size == 1 ? log::Util::Data::GetTime() : log::Util::Data::GetTime() % _cur_size; // 获取当前是第几个时间段,特殊处理任何数模1都是0的问题
        log::Util::File::Create_Dictory(_basename);                                                      // 创建目录
        _ofs.open(GetFileName(), std::ios::binary | std::ios::app);                                      // 打开文件,默认不存在会进行创建
        assert(_ofs.is_open());                                                                          // 检测是否正常打开
    }
    virtual void log(const char *data, size_t len)
    {
        time_t cur = log::Util::Data::GetTime();
        if (cur % _cur_size != _cur_gap) // 不等于当前时间段
        {
            _ofs.close();
            _cur_gap = _cur_size == 1 ? log::Util::Data::GetTime() : log::Util::Data::GetTime() % _cur_size; // 获取当前是第几个时间段,特殊处理任何数模1都是0的问题
            _ofs.open(GetFileName(), std::ios::binary | std::ios::app);
            assert(_ofs.is_open());
        }
        _ofs.write(data, len);
        if (_ofs.good() == false)
        {
            std::cerr << "日志输出失败" << std::endl;
        }
    }
    std::string GetFileName()
    {
        time_t t = time(NULL);
        struct tm tm;
        localtime_r(&t, &tm);
        std::stringstream ss;
        ss << _basename;
        ss << tm.tm_year + 1900;
        ss << tm.tm_mon + 1;
        ss << tm.tm_mday;
        ss << tm.tm_hour;
        ss << tm.tm_min;
        ss << tm.tm_sec;
        ss << ".log";
        return ss.str();
    }

private:
    std::string _basename; // 文件基础名字
    std::ofstream _ofs;    // 管理文件
    size_t _cur_gap;       // 当前时间段
    size_t _cur_size;      // 时间段大小
};

#endif